#include "stdafx.h"
#include "Progress.h"

namespace ui
{

Progress::Progress() :
	m_bHorizontal(true),
	m_bStretchForeImage(true),
	m_nMax(100),
	m_nMin(0),
	m_dValue(0.f),
	m_sProgressColor(),
	m_progressImage(),
	m_sProgressImageModify()
{
	m_sControlClassName = L"Progress";
	m_uTextStyle = DT_SINGLELINE | DT_CENTER;
	SetFixedHeight(12);
}


#if BUILD_XML_GUI	
void Progress::InitAttrVistor()
{
	__super::InitAttrVistor();
	m_attrVistor.SetAttrDefaultValue(L"align", std::to_wstring(DT_CENTER | DT_TOP));

	AttrOfClass attrs;
	ContrlAttrVistorItem item = { L"Progress" };
	attrs.push_back(item);

	//basic
	{
		std::tuple<std::wstring, std::wstring, std::wstring> AttrNameBasic[] = {
		{ L"min", L"0", L"int"}, { L"max", L"100", L"int"}, { L"value", L"0", L"double"}
		};
		int size = sizeof(AttrNameBasic) / sizeof(AttrNameBasic[0]);
		for (int i = 0; i < size; i++)
		{
			std::wstring AttrName = std::get<0>(AttrNameBasic[i]);
			item = { AttrName, std::get<1>(AttrNameBasic[i]), std::bind(&Progress::GetBuildAttrString, this, AttrName), std::bind(&Progress::SetBuildAttrString, this, AttrName, std::placeholders::_1), std::get<2>(AttrNameBasic[i]) };
			attrs.push_back(item);
		}
	}

	item = { L"progresscolor", L"", std::bind(&Progress::GetBuildAttrString, this, L"progresscolor"), std::bind(&Progress::SetBuildAttrString, this, L"progresscolor", std::placeholders::_1), L"color", m_pWindow->GetAttrColorList() };
	attrs.push_back(item);
	item = { L"progressimage", L"", std::bind(&Progress::GetBuildAttrString, this, L"progressimage"), std::bind(&Progress::SetBuildAttrString, this, L"progressimage", std::placeholders::_1), L"image"};
	attrs.push_back(item);

	//bool 
	std::pair<std::wstring, std::wstring> AttrNameBool[] = {
		{ L"hor", L"true" }, { L"isstretchfore", L"true" }
	};
	int sizeBool = sizeof(AttrNameBool) / sizeof(AttrNameBool[0]);
	for (int i = 0; i < sizeBool; i++)
	{
		std::wstring AttrName = AttrNameBool[i].first;
		item = { AttrName, AttrNameBool[i].second, std::bind(&Progress::GetBuildAttrString, this, AttrName), std::bind(&Progress::SetBuildAttrString, this, AttrName, std::placeholders::_1), L"bool",  gAttrListBool };
		attrs.push_back(item);
	}
	m_attrVistor.vecClass.emplace_back(attrs);
}

std::wstring Progress::GetBuildAttrString(std::wstring sAttr) const
{
	std::wstring V;
	if (sAttr == L"min")
		V = std::to_wstring(m_nMin);
	else if (sAttr == L"max")
		V = std::to_wstring(m_nMax);
	else if (sAttr == L"value")
		V = std::to_wstring(m_nMax);
	else if (sAttr == L"progresscolor")
		V = GetProgressColor();
	else if (sAttr == L"progressimage")
		V = GetProgressImage();
	else if (sAttr == L"hor")
		V = m_bHorizontal ? L"true" : L"false";
	else if (sAttr == L"isstretchfore")
		V = m_bStretchForeImage ? L"true" : L"false";
	else
		V = __super::GetBuildAttrString(sAttr);

	return V;
}
#endif

void Progress::SetAttribute(const std::wstring& srName, const std::wstring& strValue)
{
	if (srName == _T("hor")) SetHorizontal(strValue == _T("true"));
	else if (srName == _T("min")) SetMinValue(_ttoi(strValue.c_str()));
	else if (srName == _T("max")) SetMaxValue(_ttoi(strValue.c_str()));
	else if (srName == _T("value")) SetValue(_ttoi(strValue.c_str()));
	else if (srName == _T("progressimage")) SetProgressImage(strValue);
	else if (srName == _T("isstretchfore")) SetStretchForeImage(strValue == _T("true"));
	else if (srName == _T("progresscolor")) {
		LPCTSTR pValue = strValue.c_str();
		while (*pValue > _T('\0') && *pValue <= _T(' ')) pValue = ::CharNext(pValue);
		SetProgressColor(pValue);
	}
	else Label::SetAttribute(srName, strValue);
}

void Progress::PaintStatusImage(IRenderContext* pRender)
{
	if (m_nMax <= m_nMin) m_nMax = m_nMin + 1;
	if (m_dValue > m_nMax) m_dValue = m_nMax;
	if (m_dValue < m_nMin) m_dValue = m_nMin;

	UiRect rc = GetProgressPos();
	if (!m_sProgressColor.empty()) {
		DWORD dwProgressColor = GlobalManager::GetTextColor(m_sProgressColor);
		if (dwProgressColor != 0) {
			UiRect rcProgressColor = m_rcItem;
			if (m_bHorizontal) {
				rcProgressColor.right = rcProgressColor.left + rc.right;
			}
			else {
				rcProgressColor.top = rcProgressColor.top + rc.top;
			}
			pRender->DrawColor(rcProgressColor, dwProgressColor);
		}
	}

	if (!m_progressImage.imageAttribute.sImageString.empty()) {
		m_sProgressImageModify.clear();
		if (m_bStretchForeImage)
			m_sProgressImageModify = StringHelper::Printf(_T("destscale='false' dest='%d,%d,%d,%d'"), rc.left, rc.top, rc.right, rc.bottom);
		else
			m_sProgressImageModify = StringHelper::Printf(_T("destscale='false' dest='%d,%d,%d,%d' source='%d,%d,%d,%d'")
				, rc.left, rc.top, rc.right, rc.bottom
				, rc.left, rc.top, rc.right, rc.bottom);

		DrawImage(pRender, m_progressImage, m_sProgressImageModify);
	}
}

void Progress::ClearImageCache()
{
	__super::ClearImageCache();
	m_progressImage.ClearCache();
}

bool Progress::IsHorizontal()
{
	return m_bHorizontal;
}

void Progress::SetHorizontal(bool bHorizontal)
{
	if( m_bHorizontal == bHorizontal ) return;

	m_bHorizontal = bHorizontal;
	Invalidate();
}

int Progress::GetMinValue() const
{
	return m_nMin;
}

void Progress::SetMinValue(int nMin)
{
	m_nMin = nMin;
	Invalidate();
}

int Progress::GetMaxValue() const
{
	return m_nMax;
}

void Progress::SetMaxValue(int nMax)
{
	m_nMax = nMax;
	Invalidate();
}

double Progress::GetValue() const
{
	return m_dValue;
}

void Progress::SetValue(double nValue)
{
	m_dValue = nValue;
	Invalidate();
}

bool Progress::IsStretchForeImage()
{
	return m_bStretchForeImage;
}

void Progress::SetStretchForeImage(bool bStretchForeImage /*= true*/)
{
	if (m_bStretchForeImage == bStretchForeImage) return;
	m_bStretchForeImage = bStretchForeImage;
	Invalidate();
}

std::wstring Progress::GetProgressImage() const
{
	return m_progressImage.imageAttribute.sImageString;
}

void Progress::SetProgressImage(const std::wstring& strImage)
{
	m_progressImage.SetImageString(strImage);
	Invalidate();
}

std::wstring Progress::GetProgressColor() const
{
	return m_sProgressColor;
}

void Progress::SetProgressColor(const std::wstring& strProgressColor)
{
	ASSERT(GlobalManager::GetTextColor(strProgressColor) != 0);
	if( m_sProgressColor == strProgressColor ) return;

	m_sProgressColor = strProgressColor;
	Invalidate();
}

UiRect Progress::GetProgressPos()
{
	UiRect rc;
	if (m_bHorizontal) {
		rc.right = int((m_dValue - m_nMin) * (m_rcItem.right - m_rcItem.left) / (m_nMax - m_nMin));
		rc.bottom = m_rcItem.bottom - m_rcItem.top;
	}
	else {
		rc.top = int((m_nMax - m_dValue) * (m_rcItem.bottom - m_rcItem.top) / (m_nMax - m_nMin));
		rc.right = m_rcItem.right - m_rcItem.left;
		rc.bottom = m_rcItem.bottom - m_rcItem.top;
	}

	return rc;
}

}
